package com.xjtu.mybatisplus.service.impl.login;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xjtu.mybatisplus.common.JsonResponse;
import com.xjtu.mybatisplus.common.constant.JwtClaimsConstant;
import com.xjtu.mybatisplus.common.constant.PasswordConstant;
//import com.xjtu.mybatisplus.common.JsonResponse.JsonResponse;
import com.xjtu.mybatisplus.common.utls.MD5encrypt;
import com.xjtu.mybatisplus.common.utls.RedisUtil;
import com.xjtu.mybatisplus.mapper.UserMapper;
import com.xjtu.mybatisplus.model.domain.User;
import com.xjtu.mybatisplus.model.dto.AuthUserDto;
import com.xjtu.mybatisplus.model.dto.EmailDto;
import com.xjtu.mybatisplus.model.dto.ForgetDto;
import com.xjtu.mybatisplus.service.AuthService;
import com.xjtu.mybatisplus.service.EmailService;
import com.xjtu.mybatisplus.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//import net.oschina.j2cache.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.sql.Wrapper;
import java.time.LocalDateTime;
import java.util.Collections;

/**
 * 授权登录接口实现类
 *
 * @author zhuhuix
 * @date 2020-06-15
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class AuthServiceImpl implements AuthService {

	// 验证码放入redis缓存过期时间
//    @Value("${code.expiration}")
//    private Long expiration;

//    @Value("${rsa.private-key}")
//    private String privateKey;

    private final RedisUtil redisUtils;
    private final EmailService emailService;
    private final UserService userService;
    @Autowired
    UserMapper userMapper;

    @Override
    public JsonResponse sendMailCode(String email, String type) {
        String htmlTemplate ="";
        System.out.println("");
        switch(type){
            case "注册":
                if (userService.registerEmailExist(email)) {
                    log.info("邮箱已存在{}",email);
                    return JsonResponse.failure("注册邮箱已存在");
//            throw new RuntimeException("注册邮箱已存在");
                }
                htmlTemplate="register-code.ftl";
                break;
            case "忘记密码":
                if (!userService.registerEmailExist(email)) {
                    log.info("该邮箱未注册！{}",email);
                    return JsonResponse.failure("该邮箱未注册！");
//            throw new RuntimeException("注册邮箱已存在");
                }
                htmlTemplate="forget-code.ftl";
                break;
            default:{
                return JsonResponse.failure("未知请求");
            }

        }

        // 查看注册邮箱是否存在


        // 获取发送邮箱验证码的HTML模板
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
        Template template = engine.getTemplate(htmlTemplate);

        // 从redis缓存中尝试获取验证码
        Object code = redisUtils.get(email);
        if (code == null) {
            // 如果在缓存中未获取到验证码，则产生6位随机数，放入缓存中
            code = RandomUtil.randomNumbers(6);
            if (!redisUtils.set(email, code)) {
                return JsonResponse.failure("后台缓存服务异常");
//                throw new RuntimeException("后台缓存服务异常");
            }
        }
        log.info("验证码：{}",code);
        try {

        emailService.send(new EmailDto(Collections.singletonList(email),"邮箱验证码",template.render(Dict.create().set("code", code))));
        }catch (Exception e){
            return JsonResponse.failure("邮箱不存在");
        }
        // 发送验证码
//        emailService.send(new EmailDto(Collections.singletonList(email),
//                "邮箱验证码", template.render(Dict.create().set("code", code))));

        return JsonResponse.success("");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResponse register(AuthUserDto authUserDto) {
        // 通过email获取redis中的code
        Object value = redisUtils.get(authUserDto.getEmail());
        if (value == null || !value.toString().equals(authUserDto.getCode())) {
            return JsonResponse.failure("无效验证码");
//            throw new RuntimeException("无效验证码");
        } else {
            redisUtils.del(authUserDto.getEmail());
        }

        // 如果前端没有传入用户名，则以邮箱号作为用户名进行注册
        String userName =authUserDto.getUsername();

        if (userService.findByUserName(userName) != null) {
            return JsonResponse.failure("用户名已存在");
//            throw new RuntimeException("用户名已存在");
        }

        // 创建用户
        User user = new User();
        user.setUsername(userName);
        try {
            user.setPassword(DigestUtils.md5DigestAsHex((authUserDto.getPassword()+ PasswordConstant.SALT).getBytes()));
        } catch (Exception e) {
            return JsonResponse.failure("注册密码异常");
//            throw new RuntimeException("注册密码异常");
        }

        user.setEmail(authUserDto.getEmail());
        user.setAvator(authUserDto.getAvator());
        user.setPhone(authUserDto.getPhone());
        user.setSex(authUserDto.getSex());
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());


        return userService.create(user) != null ? JsonResponse.success("") : JsonResponse.failure("创建用户时出现异常");
    }

    @Override
    public JsonResponse forget(ForgetDto forgetDto) {

        Object value = redisUtils.get(forgetDto.getEmail());
        if (value == null || !value.toString().equals(forgetDto.getCode())) {
            return JsonResponse.failure("无效验证码");
//            throw new RuntimeException("无效验证码");
        } else {
            redisUtils.del(forgetDto.getEmail());
        }

        return userService.updateByUserEmail(forgetDto.getEmail()) ? JsonResponse.success("") : JsonResponse.failure("密码更新失败");


    }

}
